package tool.zyk.protocol;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import lombok.extern.slf4j.Slf4j;
import tool.zyk.dto.RpcOrderTypeDTO;
import tool.zyk.dto.SerializableDTO;
import tool.zyk.stardand.RpcProtocol;
import tool.zyk.utils.LogUtil;

import java.util.Optional;

/**
 * author: zyk
 * datetime: 2024/1/31 23:09
 * describe:
 */
@Slf4j
public class ProtocolM2BEncoder extends MessageToByteEncoder<RpcProtocol> {

    @Override
    protected void encode(ChannelHandlerContext ctx, RpcProtocol msg, ByteBuf out) throws Exception {
        try {
            log.info("解析RPC协议:{}", msg);
            //解析协议BO
            Optional<RpcProtocol> protocolOptional = Optional.ofNullable(msg);
            byte[] magicNum = protocolOptional.map(RpcProtocol::getMagicNum).orElseThrow(() -> new RuntimeException("魔法值为空"));
            Long requestId = protocolOptional.map(RpcProtocol::getRequestId).orElseThrow(() -> new RuntimeException("请求ID为空"));
            Integer serializableType = protocolOptional.map(RpcProtocol::getSerializableType).map(SerializableDTO::getCode).orElseThrow(() -> new RuntimeException("序列化类型为空"));
            Integer orderType = protocolOptional.map(RpcProtocol::getOrderType).map(RpcOrderTypeDTO::getOrderType).orElseThrow(() -> new RuntimeException("指令类型为空"));
            Integer dataLength = protocolOptional.map(RpcProtocol::getDataLength).orElseThrow(() -> new RuntimeException("数据长度为空"));
            byte[] dataByte = protocolOptional.map(RpcProtocol::getData).orElseThrow(() -> new RuntimeException("传输数据为空"));
            //写数据
            log.debug("编码 magicNum：{}", magicNum);
            out.writeBytes(magicNum);
            log.debug("编码 requestId：{}", requestId);
            out.writeLong(requestId);
            log.debug("编码 serializableType：{}", serializableType);
            out.writeInt(serializableType);
            log.debug("编码 orderType：{}", orderType);
            out.writeInt(orderType);
            log.debug("编码 dataLength：{}", dataLength);
            out.writeInt(dataLength);
            log.debug("编码 dataByte：{}", dataByte);
            out.writeBytes(dataByte);

        } catch (Throwable throwable) {
            LogUtil.printErrorLog(throwable);
            throw new RuntimeException(throwable);
        }
    }
}
